package service

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"ollama-go/config"
	"ollama-go/toolkit"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/androidsr/sc-go/sc"
	"github.com/androidsr/sc-go/shttp"
	"github.com/tmc/langchaingo/llms"
)

type FlowActuator struct {
	defaultModel  string
	Headers       map[string]string
	Nodes         []*Node  `json:"nodes"`
	Edges         []*Edges `json:"edges"`
	flowId        string
	variables     map[string][]map[string]any
	parameterName string
	callback      func(string, error)
	forData       []interface{}
	forStart      []*Node
	current       *Node
	forIndex      int64
}

type Node struct {
	Id         string         `json:"id"`
	NodeType   string         `json:"type"`
	Properties map[string]any `json:"properties"`
	Text       map[string]any `json:"text"`
}

type Edges struct {
	Id           string         `json:"id"`
	EdgeType     string         `json:"edgeType"`
	SourceNodeId string         `json:"sourceNodeId"`
	TargetNodeId string         `json:"targetNodeId"`
	Text         map[string]any `json:"text"`
	Properties   map[string]any `json:"properties"`
}

func NewFlowActuator(flowId string, callback func(string, error)) *FlowActuator {
	m := new(FlowActuator)
	m.flowId = flowId
	m.callback = callback
	fwConfig := NewFwConfigService().Get(flowId)
	if fwConfig.Content == "" {
		log.Printf("流程信息未配置\n")
		return nil
	}
	err := json.Unmarshal([]byte(fwConfig.Content), m)
	if err != nil {
		log.Printf("流程配置不正确：%s", err.Error())
		return nil
	}
	m.variables = make(map[string][]map[string]any, 0)

	if config.CFG.Llm.Ollama.Enable {
		m.defaultModel = config.CFG.Llm.Ollama.Model
	} else {
		m.defaultModel = config.CFG.Llm.Openai.Model
	}
	return m
}

// 打印输出
func (m *FlowActuator) printOutput(name, content string) {
	m.callback(fmt.Sprintf("#### %s %s 输出 \n%s  \n", name, sc.FormatDateTimeString(time.Now()), content), nil)
}

// 打印输入
func (m *FlowActuator) printInput(name, content string) {
	m.callback(fmt.Sprintf("#### %s %s 输入 \n%s  \n", name, sc.FormatDateTimeString(time.Now()), content), nil)
}

// 获取开始节点
func (m *FlowActuator) GetStart() *Node {
	for _, v := range m.Nodes {
		if v.NodeType == "StartNode" {
			return v
		}
	}
	return nil
}

// 获取当前节点
func (m *FlowActuator) GetCurrent(id string) []*Node {
	nodes := make([]*Node, 0)
	for _, v := range m.Nodes {
		if v.Id == id {
			nodes = append(nodes, v)
		}
	}
	return nodes
}

// 获取结束节点
func (m *FlowActuator) GetEnd() *Node {
	for _, v := range m.Nodes {
		if v.NodeType == "EndNode" {
			return v
		}
	}
	return nil
}

// 获取下一个节点
func (m *FlowActuator) GetNext(current string) []*Node {
	var targetNodeId string
	isfor := false
	for _, v := range m.Edges {
		if v.SourceNodeId == current {
			if v.Properties != nil {
				if v.Properties["forType"] == "1" {
					isfor = true
					str := m.GetVariable(v.Properties["forData"].(string))
					if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) {
						str = str[1 : len(str)-1]
					}
					str = strings.ReplaceAll(str, "\\", "")
					var data []interface{}
					err := json.Unmarshal([]byte(str), &data)
					if err == nil {
						forSize, ok := v.Properties["forSize"].(float64)
						if ok {
							m.forData = data[0:int(forSize)]
						} else {
							m.forData = data
						}
					} else {
						fmt.Println("解析JSON出错 ：", err)
					}
					if m.variables["for"] == nil {
						m.variables["for"] = make([]map[string]any, 0)
						m.variables["for"] = append(m.variables["for"], map[string]any{})
					}
					m.variables["for"][0]["item"] = m.forData[0]
					m.forIndex = 0
				} else if v.Properties["forType"] == "2" {
					if len(m.forData) > 1 {
						m.forIndex++
						m.forData = m.forData[1:]
						m.variables["for"][0]["item"] = m.forData[0]
						return m.forStart
					}
				}
				value1, ok := v.Properties["startCondition"].(string)
				if !ok {
					targetNodeId = v.TargetNodeId
					break
				}
				value2, ok := v.Properties["endCondition"].(string)
				if !ok {
					targetNodeId = v.TargetNodeId
					break
				}
				expression, ok := v.Properties["expression"].(string)
				if !ok {
					targetNodeId = v.TargetNodeId
					break
				}
				if value1 != "" && value2 != "" && !m.IsExpression(expression, value1, value2) {
					continue
				}
				targetNodeId = v.TargetNodeId
				break
			}
			targetNodeId = v.TargetNodeId
			break
		}
	}
	node := m.GetCurrent(targetNodeId)
	if isfor {
		m.forStart = node
	}
	return node

}

// 开始执行流程
func (m *FlowActuator) StartFlow(startData map[string]any) error {
	m.variables["input"] = make([]map[string]any, 0)
	m.variables["input"] = append(m.variables["input"], startData)
	m.current = m.GetStart()
	var err error
	var result map[string]interface{}
	for {
		nodes := m.GetNext(m.current.Id)
		if len(nodes) == 0 || nodes[0].NodeType == "EndNode" {
			fmt.Println("结束")
			result = m.GetEndResult(nodes[0])
			break
		}
		var ok bool
		for _, current := range nodes {
			m.current = current
			m.parameterName, ok = m.current.Properties["parameterName"].(string)
			if !ok {
				continue
			}
			switch m.current.NodeType {
			case "FunctionNode":
				err = m.completeFunctionNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			case "LLMNode":
				err = m.completeLLMNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			case "VectorNode":
				err = m.completeVectorNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			case "HttpNode":
				err = m.completeHttpNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			case "DatabaseNode":
				err = m.completeDatabaseNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			case "BugNode":
				err = m.completeBugNode(m.current)
				if err != nil {
					m.callback("", err)
					return err
				}
			}
		}
	}
	log.Println("流程执行完成.")
	if err != nil {
		m.callback("", err)
	} else {
		bs, err := json.Marshal(result)
		if err != nil {
			return err
		}
		m.callback(string(bs), err)
	}
	return err
}

// 获取返回参数
func (m *FlowActuator) GetEndResult(endNode *Node) map[string]interface{} {
	vars := endNode.Properties
	result := make(map[string]interface{}, 0)
	messages, ok := vars["messages"].([]interface{})
	if !ok {
		return result
	}
	for _, v := range messages {
		vmap := v.(map[string]interface{})
		varName := vmap["varName"].(string)
		varValue := vmap["varValue"].(string)
		result[varName] = m.GetVariable(varValue)
	}
	return result
}

// 执行问答
func (m *FlowActuator) completeLLMNode(current *Node) error {
	vars := current.Properties
	name := vars["name"].(string)
	model, ok := vars["model"].(string)
	if !ok {
		model = m.defaultModel
	}
	parameterName := vars["parameterName"].(string)
	messages := vars["messages"].([]interface{})
	resultHistory := vars["resultHistory"].(bool)
	inputHistory := vars["resultHistory"].(bool)
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}

	llm := toolkit.GetLLM(model)
	llm.SetContent(m.AddContent(messages)...)
	if printInput {
		bs, _ := json.Marshal(llm.GetContent())
		m.printInput(name, string(bs))
	}
	resp, err := llm.GenerateCallback(context.Background(), nil)
	if err != nil {
		log.Printf("流程执行检索失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
		return err
	}
	data := resp.Choices[0].Content
	if printOutput {
		m.printOutput(name, data)
	}
	history := make(map[string]any, 0)
	if inputHistory {
		history["input"] = messages
	}
	if resultHistory {
		history["output"] = data
	}
	m.variables[parameterName] = append(m.variables[parameterName], history)
	return nil
}

// 执行知识库
func (m *FlowActuator) completeVectorNode(current *Node) error {
	vars := current.Properties
	name := vars["name"].(string)
	model, ok := vars["model"].(string)
	if !ok {
		model = m.defaultModel
	}
	parameterName := vars["parameterName"].(string)
	limit := vars["limit"].(float64)
	collectionName := vars["collectionName"].(string)
	filename := vars["filename"].(string)
	system := vars["system"].(string)
	message := vars["message"].(string)
	similarityScore := vars["similarityScore"].(float64)
	resultHistory := vars["resultHistory"].(bool)
	inputHistory := vars["resultHistory"].(bool)
	analyse := vars["analyse"].(bool)
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}

	message = m.GetVariable(message)
	ctx := context.Background()
	query := toolkit.SearchDTO{
		CollectionName: collectionName,
		Query:          message,
		Limit:          int(limit),
		Score:          float32(similarityScore),
		Filter:         map[string]any{"filename": filename},
	}
	docs, err := toolkit.PG.SetStore(ctx, collectionName).Search(ctx, &query)
	if err != nil {
		return err
	}
	content := bytes.Buffer{}
	for _, doc := range docs {
		content.WriteString(doc.PageContent)
	}
	history := make(map[string]any, 0)
	if !analyse && resultHistory {
		history["output"] = content.String()
		if printOutput {
			m.printOutput(name, content.String())
		}
		m.variables[parameterName] = append(m.variables[parameterName], history)
		return nil
	}

	llm := toolkit.GetLLM(model)
	if system != "" {
		llm.SetContent(llms.TextParts(llms.ChatMessageTypeSystem, system))
	}
	inputMsg := content.String() + message
	llm.SetContent(llms.TextParts(llms.ChatMessageTypeHuman, inputMsg))
	if printInput {
		bs, _ := json.Marshal(llm.GetContent())
		m.printInput(name, string(bs))
	}
	resp, err := llm.GenerateCallback(ctx, nil)
	if err != nil {
		log.Printf("流程执行检索失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
		return err
	}
	data := resp.Choices[0].Content
	if printOutput {
		m.printOutput(name, data)
	}
	if inputHistory {
		history["input"] = []map[string]any{{"human": inputMsg}}
	}
	if resultHistory {
		history["output"] = data
	}
	m.variables[parameterName] = append(m.variables[parameterName], history)
	return nil
}

// 执行函数
func (m *FlowActuator) completeFunctionNode(current *Node) error {
	vars := current.Properties
	parameterName, ok := vars["parameterName"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["parameterName"]))
	}
	model, ok := vars["model"].(string)
	if !ok {
		model = m.defaultModel
	}
	name, ok := vars["name"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["name"]))
	}
	funcCall, ok := vars["funcCall"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["funcCall"]))
	}
	messages, ok := vars["messages"].([]interface{})
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["messages"]))
	}
	resultHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	inputHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}
	funcContent := NewOllamaFunctionsService().Get(funcCall).FuncContent
	llm := toolkit.GetLLM(model)

	llm.SetContent(m.AddContent(messages)...)
	if printInput {
		bs, _ := json.Marshal(llm.GetContent())
		m.printInput(name, string(bs))
	}
	data, err := llm.GenerateFunction(context.Background(), "["+funcContent+"]", func(fun *llms.FunctionCall) (bool, string, error) {
		return ExecFuncCall(fun)
	}, nil)
	if err != nil {
		log.Printf("流程执行函数失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
		return err
	}
	if printOutput {
		m.printOutput(name, data)
	}
	history := make(map[string]any, 0)
	if inputHistory {
		history["input"] = messages
	}
	if resultHistory {
		history["output"] = data
	}
	m.variables[parameterName] = append(m.variables[parameterName], history)
	return nil
}

// 执行HTTP调用
func (m *FlowActuator) completeHttpNode(current *Node) error {
	vars := current.Properties
	parameterName, ok := vars["parameterName"].(string)
	if !ok {
		return errors.New("参数类型不正确：parameterName" + fmt.Sprint(vars["parameterName"]))
	}
	url, ok := vars["url"].(string)
	if !ok {
		return errors.New("参数类型不正确：url" + fmt.Sprint(vars["url"]))
	}
	name, ok := vars["name"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["name"]))
	}
	contentType, ok := vars["contentType"].(string)
	if !ok {
		return errors.New("参数类型不正确：contentType" + fmt.Sprint(vars["contentType"]))
	}
	method, ok := vars["method"].(string)
	if !ok {
		return errors.New("参数类型不正确：method" + fmt.Sprint(vars["method"]))
	}
	headerStr, ok := vars["headers"].(string)
	if !ok {
		headerStr = ""
	}
	cookieStr, ok := vars["cookies"].(string)
	if !ok {
		cookieStr = ""
	}
	body, ok := vars["body"].(string)
	if !ok {
		body = ""
	}
	validateKey, ok := vars["validateKey"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["validateKey"]))
	}
	expression, ok := vars["expression"].(string)
	if !ok {
		return errors.New("参数类型不正确：expression" + fmt.Sprint(vars["expression"]))
	}
	validateValue, ok := vars["validateValue"].(string)
	if !ok {
		return errors.New("参数类型不正确：validateValue")
	}
	dataKey, ok := vars["dataKey"].(string)
	if !ok {
		dataKey = ""
	}
	resultHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：resultHistory")
	}
	inputHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：resultHistory")
	}
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}

	body = m.GetVariable(body)
	url = strings.TrimSpace(m.GetVariable(url))
	if printInput && body != "" {
		bs, err := json.Marshal(body)
		var p any
		if err != nil {
			p = body
		} else {
			p = string(bs)
		}
		m.printInput(name, fmt.Sprint(p))
	}
	params := make(map[string]interface{}, 0)
	if method != "GET" && body != "" {
		err := json.Unmarshal([]byte(body), &params)
		if err != nil {
			log.Printf("流程执行函数失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
			return errors.New("参数格式不正确！")
		}
	}
	headers := make(map[string]string, 0)
	if headerStr != "" {
		kvs := strings.Split(headerStr, ";")
		for _, v := range kvs {
			if strings.Contains(v, "=") {
				kv := strings.Split(v, "=")
				headers[kv[0]] = kv[1]
			}
		}
	}
	if cookieStr != "" {
		headers["Cookie"] = cookieStr
	}
	if len(headers) > 0 {
		m.Headers = headers
	}
	var data []byte
	var err error
	switch method {
	case "GET":
		data, err = shttp.Get(url+body, contentType, m.Headers)
	case "POST":
		data, err = shttp.Post(url, strings.TrimSpace(contentType), m.Headers, params)
	case "PUT":
		data, err = shttp.Put(url, contentType, m.Headers, params)
	case "DELETE":
		data, err = shttp.Delete(url, contentType, m.Headers, params)
	}
	if err != nil {
		fmt.Println(err)
		return err
	}

	var result interface{}
	resultMap := make(map[string]interface{}, 0)
	err = json.Unmarshal(data, &resultMap)
	if err != nil {
		result = string(data)
	}
	if validateKey != "" && expression != "" && validateValue != "" && len(resultMap) != 0 {
		if !m.IsExpression(expression, fmt.Sprint(resultMap[validateKey]), validateValue) {
			return errors.New("响应数据失败：" + string(data))
		}
		if dataKey != "" {
			result = resultMap[dataKey]
		} else {
			result = resultMap
		}
	} else {
		if resultMap != nil {
			result = resultMap
		}
	}

	if printOutput {
		bs, err := json.Marshal(result)
		var p any
		if err != nil {
			p = body
		} else {
			p = string(bs)
		}
		m.printOutput(name, fmt.Sprint(p))
	}
	history := make(map[string]any, 0)
	if inputHistory {
		history["input"] = body
	}
	if resultHistory {
		history["output"] = result
	}
	m.variables[parameterName] = append(m.variables[parameterName], history)
	return nil
}

// 执行数据库调用
func (m *FlowActuator) completeDatabaseNode(current *Node) error {
	vars := current.Properties
	parameterName, ok := vars["parameterName"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["parameterName"]))
	}
	name, ok := vars["name"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["name"]))
	}
	sourceId, ok := vars["sourceId"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["sourceId"]))
	}
	sql, ok := vars["sql"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["sql"]))
	}
	wheres, ok := vars["wheres"].([]interface{})
	if !ok {
		wheres = make([]interface{}, 0)
	}
	args, ok := vars["args"].(string)
	if !ok {
		args = ""
	}
	resultHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	inputHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}

	args = m.GetVariable(args)
	if printInput && args != "" {
		m.printInput(name, fmt.Sprint(args))
	}
	params := make(map[string]interface{}, 0)
	if args != "" {
		err := json.Unmarshal([]byte(args), &params)
		if err != nil {
			log.Printf("流程执行DB失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
			return errors.New("参数格式不正确！")
		}
	}
	database := NewDbDataSourceService()
	info := database.Get(sourceId)
	db, err := database.GetConnect(info.DbType, info.Url)
	if err != nil {
		log.Printf("获取数据库连接失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
		return err
	}
	var whereString string
	for _, w := range wheres {
		sqlWhere := fmt.Sprint(w)
		re := regexp.MustCompile(`#\{([^}]*)\}`)
		matches := re.FindStringSubmatch(sqlWhere)
		if len(matches) <= 1 {
			continue
		}
		key := matches[1]
		value := params[key]
		if value == nil || value == "" {
			continue
		}
		whereString += strings.ReplaceAll(sqlWhere, "#{"+key+"}", " '"+fmt.Sprint(value)+"' ")
	}
	sql = strings.ReplaceAll(sql, "$where", whereString)
	result, err := database.QuerySql(db, sql)
	if err != nil {
		log.Printf("执行SQL语句失败： (%s - %s) 错误信息：%v\n", parameterName, name, err)
		return err
	}
	if printOutput {
		bs, err := json.Marshal(result)
		if err != nil {
			m.printOutput(name, fmt.Sprint(result))
		} else {
			m.printOutput(name, string(bs))
		}
	}
	history := make(map[string]any, 0)
	if inputHistory {
		history["input"] = params
	}
	if resultHistory {
		history["output"] = result
	}
	m.variables[parameterName] = append(m.variables[parameterName], history)
	return nil
}

// 爬虫
func (m *FlowActuator) completeBugNode(current *Node) error {
	vars := current.Properties
	parameterName, ok := vars["parameterName"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["parameterName"]))
	}
	name, ok := vars["name"].(string)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["name"]))
	}
	bugType, ok := vars["bugType"].(string)
	if !ok {
		return errors.New("参数类型不正确【bugType】：" + fmt.Sprint(vars["bugType"]))
	}
	website, ok := vars["website"].(string)
	if !ok {
		return errors.New("参数类型不正确【website】：" + fmt.Sprint(vars["website"]))
	}
	text, ok := vars["text"].(string)
	if !ok {
		text = ""
	}
	selecters, ok := vars["selecters"].([]interface{})
	if !ok {
		selecters = make([]interface{}, 0)
	}
	resultHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	inputHistory, ok := vars["resultHistory"].(bool)
	if !ok {
		return errors.New("参数类型不正确：" + fmt.Sprint(vars["resultHistory"]))
	}
	printOutput, ok := vars["printOutput"].(bool)
	if !ok {
		printOutput = false
	}
	printInput, ok := vars["printInput"].(bool)
	if !ok {
		printInput = false
	}
	websites := make([]string, 0)
	if website != "" && strings.HasPrefix(website, "$") {
		website = m.GetVariable(website)
		err := json.Unmarshal([]byte(website), &websites)
		if err != nil {
			websites = append(websites, website)
		}
		text = ""
	} else {
		websites = append(websites, website)
	}

	if text != "" && strings.HasPrefix(text, "$") {
		text = m.GetVariable(text)
	}

	result := make([]map[string]interface{}, 0)
	for _, w := range websites {
		var v = w
		if strings.HasPrefix(w, `"`) {
			v = w[1:]
		}
		if strings.HasSuffix(w, `"`) {
			v = v[:len(v)-1]
		}
		var url = v + text
		if printInput {
			m.printInput(name, url)
		}
		ch := NewChromedp()
		if bugType == "link" {
			if len(selecters) == 0 {
				selecters = append(selecters, map[string]string{"selecter": "body", "selecterKey": "body a"})
			}
			html := ch.GetHtml(url)
			if html == "" {
				continue
			}
			for _, selecter := range selecters {
				item := selecter.(map[string]interface{})
				links := ch.GetLinkByContent(html, item["selecter"].(string))
				if len(links) != 0 {
					v := make(map[string]interface{})
					v[item["selecterKey"].(string)] = unique(links)
					result = append(result, v)
				}
			}
		} else if bugType == "text" {
			if len(selecters) == 0 {
				text, err := ch.GetContent(url, "body")
				if err != nil {
					fmt.Println("获取内容失败", err)
					continue
				}
				if text != "" {
					v := make(map[string]interface{})
					v["body"] = text
					result = append(result, v)
				}
			} else {
				html := ch.GetHtml(url)
				if html == "" {
					continue
				}
				for _, selecter := range selecters {
					item := selecter.(map[string]interface{})
					texts := ch.GetContentBySelecter(html, item["selecter"].(string))
					if len(texts) != 0 {
						v := make(map[string]interface{})
						key := item["selecterKey"].(string)
						v[key] = strings.Join(texts, " "+key+" ")
						result = append(result, v)
					}
				}
			}
		}
		if printOutput {
			bs, err := json.Marshal(result)
			if err != nil {
				m.printOutput(name, fmt.Sprint(result))
			} else {
				m.printOutput(name, string(bs))
			}
		}
	}
	history := make(map[string]any, 0)
	if inputHistory {
		history["input"] = websites
	}
	if resultHistory {
		history["output"] = result
	}
	if m.variables[parameterName] == nil {
		m.variables[parameterName] = make([]map[string]any, 0)
		m.variables[parameterName] = append(m.variables[parameterName], history)
	} else {
		m.variables[parameterName] = append(m.variables[parameterName], history)
	}
	return nil
}

func unique(arr []string) []string {
	occurred := map[string]bool{}
	result := []string{}
	for e := range arr {
		if !occurred[arr[e]] {
			occurred[arr[e]] = true
			result = append(result, arr[e])
		}
	}
	return result
}

func (m *FlowActuator) AddContent(messages []interface{}) []llms.MessageContent {
	result := make([]llms.MessageContent, 0)
	for _, v := range messages {
		vv := v.(map[string]interface{})
		messageType := vv["messageType"].(string)
		message := vv["message"].(string)
		if message == "" {
			continue
		}
		message = m.GetVariable(message)
		result = append(result, llms.TextParts(llms.ChatMessageType(messageType), message))
	}
	return result
}

// 获取表达式
func (m *FlowActuator) GetVariable(messages string) string {
	pattern := `\$[a-zA-Z0-9\[\]_.]+|strings\.substring\(\s*\$[a-zA-Z0-9_.]+\s*,\s*[^,]+\s*,\s*[^)]+\s*\)`

	// 编译正则表达式
	r, err := regexp.Compile(pattern)
	if err != nil {
		log.Println("Error compiling regex:", err)
		return messages
	}
	matches := r.FindAllString(messages, -1)
	for _, message := range matches {
		oldMessage := message
		var subStart, subEnd string
		key := "strings.substring("
		if strings.HasPrefix(message, key) {
			sidx := strings.Index(message, key)
			eidx := strings.LastIndex(message, ")")
			subStr := message[sidx+len(key) : eidx]

			sub := strings.Split(subStr, ",")
			if len(sub) == 3 {
				message = strings.TrimSpace(sub[0])
				subStart = strings.TrimSpace(sub[1])
				subEnd = strings.TrimSpace(sub[2])
			}
		}
		if strings.Contains(message, ".") {
			keys := strings.Split(message[1:], ".")
			if len(keys) < 2 {
				return ""
			}

			var value any
			var values = make([]any, 0)
			valueMap := m.variables[keys[0]]
			i := 1
			if len(keys) >= 3 && keys[2] == "i" {
				i++
				value = m.GetItemVariable(i, keys, valueMap[m.forIndex])
				values = append(values, value)
			} else {
				if contains(keys, "i") {
					n := m.forIndex
					if len(valueMap) <= int(n) {
						n = int64(len(valueMap) - 1)
					}
					value = valueMap[n]
					value = m.GetItemVariable(i, keys, value)
					values = append(values, value)
				} else {
					for _, v := range valueMap {
						value = v
						value = m.GetItemVariable(i, keys, value)
						values = append(values, value)
					}
				}
			}

			if len(values) == 1 {
				value = values[0]
				if reflect.TypeOf(value).String() == "string" {
					message = value.(string)
				} else {
					bs, _ := json.Marshal(value)
					message = string(bs)
				}
			} else {
				bs, _ := json.Marshal(values)
				message = string(bs)
			}

			if subStart != "" && subEnd != "" {
				s := strings.Index(message, subStart)
				e := strings.Index(message, subEnd)
				if s != -1 && e != -1 {
					messages = strings.Replace(messages, oldMessage, message[s+len(subStart):e], 1)
				} else {
					messages = strings.Replace(messages, oldMessage, message, 1)
				}
			} else {
				messages = strings.Replace(messages, oldMessage, message, 1)
			}
		}
	}
	return messages
}

func contains(arr []string, target string) bool {
	for _, v := range arr {
		if v == target {
			return true
		}
	}
	return false
}

func (m *FlowActuator) GetItemVariable(i int, keys []string, value any) any {
	for ; i < len(keys); i++ {
		k := keys[i]
		if value == nil {
			break
		}
		if reflect.TypeOf(value).String() == "string" {
			err := json.Unmarshal([]byte(value.(string)), &value)
			if err != nil {
				fmt.Println("字符串转换错误：", err)
				break
			}
		}
		if v, ok := value.(map[string]interface{}); ok {
			value = v[k]
		} else if vs, ok := value.([]map[string]interface{}); ok && len(vs) != 0 {
			if i < len(keys)-1 {
				var n int64
				i++
				nk := keys[i]
				if nk == "i" {
					n = m.forIndex
				} else {
					var err error
					n, err = strconv.ParseInt(nk, 10, 64)
					if err != nil {
						log.Printf("这是一个切片，下一个标签节点应该是下标：%s\n", err)
						break
					}
				}

				if len(vs) <= int(n) {
					n = int64(len(vs) - 1)
				}
				value = vs[n]
			}
		}
	}
	return value
}

// 判断条件是否满足
func (m *FlowActuator) IsExpression(expression string, value1, value2 string) bool {
	if strings.HasPrefix(value1, "$") {
		value1 = m.GetVariable(value1)
	}

	if strings.HasPrefix(value2, "$") {
		value2 = m.GetVariable(value2)
	}
	switch expression {
	case "=":
		return value1 == value2
	case "!=":
		return value1 != value2
	case ">":
		v1, err := strconv.ParseFloat(value1, 64)
		if err != nil {
			return false
		}
		v2, err := strconv.ParseFloat(value2, 64)
		if err != nil {
			return false
		}
		return v1 > v2
	case ">=":
		v1, err := strconv.ParseFloat(value1, 64)
		if err != nil {
			return false
		}
		v2, err := strconv.ParseFloat(value2, 64)
		if err != nil {
			return false
		}
		return v1 >= v2
	case "<":
		v1, err := strconv.ParseFloat(value1, 64)
		if err != nil {
			return false
		}
		v2, err := strconv.ParseFloat(value2, 64)
		if err != nil {
			return false
		}
		return v1 < v2
	case "<=":
		v1, err := strconv.ParseFloat(value1, 64)
		if err != nil {
			return false
		}
		v2, err := strconv.ParseFloat(value2, 64)
		if err != nil {
			return false
		}
		return v1 <= v2
	case "include":
		return strings.Contains(value1, value2)
	case "exclusive":
		return !strings.Contains(value1, value2)
	case "startWith":
		return strings.HasPrefix(value1, value2)
	case "endWith":
		return strings.HasSuffix(value1, value2)
	case "size":
		size, err := strconv.ParseInt(value2, 10, 64)
		if err != nil {
			return false
		}
		return len(value1) == int(size)
	}
	return false
}
